package com.example.deliveryapplication

import android.content.ComponentName
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.annotation.InspectableProperty.ValueType
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider.getUriForFile
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.deliveryapplication.entity.*
import com.example.deliveryapplication.sql.AppDatabase
import com.example.deliveryapplication.utils.ExcelUtils
import com.example.deliveryapplication.wiget.AddPlanDialog
import com.obs.services.ObsClient
import com.obs.services.exception.ObsException
import com.obs.services.model.HeaderResponse
import com.obs.services.model.PutObjectRequest
import kotlinx.android.synthetic.main.activity_new_plan.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
import java.io.FileInputStream
import java.io.IOException


class NewPlanActivity : AppCompatActivity(), AddPlanDialog.CallBack,PlanItemListAdapter.CallBack {
    private val bearingModelDao by lazy { AppDatabase.getDatabase(this).bearingModelDao() }
    private val clientDao by lazy { AppDatabase.getDatabase(this).clientDao() }
    private val cuDao by lazy { AppDatabase.getDatabase(this).cuDao() }
    private val planItemDao by lazy { AppDatabase.getDatabase(this).planItemDao() }
    private val planDao by lazy { AppDatabase.getDatabase(this).planDao() }
    private val mViewModel by lazy { ViewModelProvider(this)[NewPlanViewModel::class.java] }
    private val clientList = ArrayList<SelectString>()
    private val modelList = ArrayList<SelectString>()
    private var planId = ""
    private val mList = ArrayList<PlanItemWithClientList>()

    private var canExit = false
    private var selectPosition = -1
    private var cuList=ArrayList<SelectString>()
    //0新增 1详情 2复制新表
    private val whereFrom by lazy { intent.getIntExtra("whereFrom", 0) }

    private val mAdapter by lazy { PlanItemListAdapter(this, mList,this,whereFrom) }
    private var recordList: ArrayList<Any>? = null
    private val title = arrayOf( "类型","型号", "计划数量","单位","备注")
    private var file: File? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_new_plan)

        when (whereFrom) {
            0 -> {
                //mAdapter.setCanEdit(true)
                planId = getNewUUid()
                initData()
            }
            1 -> {
                mTitleTV.setTitle("计划表详情")
                planId = intent.getStringExtra("planId") ?: ""
                mAddItemBTN.visibility = View.GONE
                mConfirmBTN.text = "分享"
                initData()
            }
            2 -> {
                mTitleTV.setTitle("复制计划表")
                //mAdapter.setCanEdit(true)
                planId = getNewUUid()
                val lastPlanId = intent.getStringExtra("planId") ?: ""
                copyData(lastPlanId)
            }
        }
        mViewModel.copyPlanResult.observe(this) {
            initData()
        }
        mRecycleView.layoutManager = LinearLayoutManager(this)
        mRecycleView.adapter = mAdapter
        mViewModel.clientResult.observe(this) { list ->
            list.forEach {
                val selectString = SelectString()
                selectString.code = it.id
                selectString.name = it.name
                clientList.add(selectString)
            }
        }
        mViewModel.planItemResult.observe(this) { list ->

            mList.clear()
            mList.addAll(dealData(list))
            mAdapter.notifyDataSetChanged()

        }
        mViewModel.modelResult.observe(this) { list ->
            list.forEach {
                val selectString = SelectString()
                selectString.code = it.id
                selectString.name = "${it.type}-${it.name}"
                modelList.add(selectString)
            }
        }
        mViewModel.insertPlanItemResult.observe(this) {
            showToast("添加成功")
            getData()
        }
        mViewModel.deletePlanItemResult.observe(this) {
            when (it) {
                0 -> {
                    showToast("删除失败")
                }
                1 -> {
                    showToast("删除成功")
//                    if (selectPosition != -1) {
//                        mAdapter.removeAt(selectPosition, mList.size)
//                        mList.removeAt(selectPosition)
//                    }
                    initData()
                }
            }
        }
//        mViewModel.getPlanResult.observe(this){list->
//            val plan=Plan(planId,"",0)
//            if(list.isEmpty()){
//                mViewModel.insertPlan(planDao,plan)
//            }else{
//                mViewModel.updatePlan(planDao,plan)
//            }
//        }
        mViewModel.updatePlanResult.observe(this) {
            if (canExit) {
                showToast("完成")
                finish()
            } else {

            }
        }
        mViewModel.cuResult.observe(this){list->
            cuList.clear()
            list.forEach {
                val selectString=SelectString()
                selectString.name=it.name
                cuList.add(selectString)
            }
        }
        mAddItemBTN.setOnClickListener {
            val dialog = AddPlanDialog(this)
            dialog.setCUList(cuList)
            dialog.setListener(this)
            dialog.setClientList(clientList)
            dialog.setTypeList(modelList)
            dialog.show()
        }
        mConfirmBTN.setOnClickListener {
            if (whereFrom != 1) {
                canExit = true
                //val plan=Plan(planId,handlerCurrentTimeToStandardString(System.currentTimeMillis()),1)
                mViewModel.updatePlan(
                    planDao,
                    planId,
                    1,
                    handlerCurrentTimeToStandardString(System.currentTimeMillis())
                )
            } else {
                exportExcel()
                //shareText2WechatFriend(this,"124")
//                PermissionX.init(this)
//                    .permissions(android.Manifest.permission.READ_EXTERNAL_STORAGE)
//                    .request { allGranted, grantedList, deniedList ->
//                        if (allGranted) {
//                            // 权限已授予
//                            // 在这里执行相机相关的操作
//                            exportExcel()
//                        } else {
//                            // 权限被拒绝
//                            // 在这里处理权限被拒绝的情况
//                        }
//                    }
            }
            //getData()
        }
    }

    fun initData() {
        mViewModel.getAllCU(cuDao)
        mViewModel.getAllClient(clientDao)
        mViewModel.getAllModel(bearingModelDao)
        getData()
    }

    fun getData() {
        Log.d("测试", planId)
        mViewModel.getAllPlanItem(planItemDao, planId)
    }

    fun copyData(lastPlanId: String) {
        mViewModel.copyPlan(planDao, planItemDao, lastPlanId, planId)
    }

    override fun onConfirmClick(name: String, data: SelectString, data2: SelectString,remark:String,cu:String) {
        var flag=true
        mList.forEach {
            if(it.clientId==data2.code){
                it.list?.forEach {
                    if(it.model.id==data.code){
                        flag=false
                    }
                }
            }

        }
        if(flag){
            val bean = PlanItem(getNewUUid(), planId, data2.code, data.code, name.toInt(),remark,cu)
            mViewModel.insertPlanItem(planDao, planItemDao, bean)
        }else{
            showToast("该公司已经有同型号的计划存在，请先删除再重新添加")
        }

    }

//    override fun onItemDelete(position: Int, data: PlanItemWithClient) {
//        selectPosition = position
//        mViewModel.deletePlanItem(planItemDao, data.planItem)
//    }

    /**
     * 导出excel
     * @param view
     */
    fun exportExcel() {
         val file = File(filesDir, "my_docs")
        val newFile=File(file, "计划表.xls")
        val fileName = newFile.path
        makeDir(file!!)
        ExcelUtils.initExcel(fileName, title)
        ExcelUtils.writePlanToExcel(mList,title,fileName,this)
        //ExcelUtils.writeObjListToExcel<Any>(getRecordData(), fileName, this)
        val uri=getUriForFile(this, "com.example.deliveryapplication.fileprovider", newFile)
        shareToWX(uri)
        val scope = CoroutineScope(Dispatchers.Default)

        // 定义一个异步函数
        @RequiresApi(Build.VERSION_CODES.N)
        fun asyncTask() {
            // 在这里执行长时间运行的操作
            val folderName: String = formatTime(System.currentTimeMillis(),"yyyyMMddHHmmss") + "_database/"
            val dbFile = getDatabasePath("app_database")
            val shmFile = getDatabasePath("app_database-shm")
            val walFile = getDatabasePath("app_database-wal")
            val dbPath = dbFile.absolutePath
            Log.d("测试",dbFile.path)
//            val sourceFile = File(dbPath)
//            val targetFile = File(filesDir, "app_database_copy")
            //sourceFile.copyTo(targetFile, true)
            //File( "${getFilesDir()}", "app_database.db")

            newUpLoad("${folderName}${dbFile.name}",dbFile)
            newUpLoad("${folderName}${shmFile.name}",shmFile)
            newUpLoad("${folderName}${walFile.name}",walFile)
            println("异步任务完成")
        }

        // 在后台线程中异步执行函数
        scope.launch {
            asyncTask()
        }


    }
    fun shareToWX(uri:Uri){
        //if (PlatformUtil.isInstallApp(this, PlatformUtil.PACKAGE_WECHAT)) {
            val share = Intent(Intent.ACTION_SEND)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

                share.putExtra(Intent.EXTRA_STREAM, uri)
                share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            } else {
                share.putExtra(Intent.EXTRA_STREAM, uri)
            }
            val cop = ComponentName("com.tencent.mm", "com.tencent.mm.ui.tools.ShareImgUI")
            share.component = cop
            share.type = "application/vnd.ms-excel" //此处可发送多种文件
            share.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            startActivity(Intent.createChooser(share, "分享文件"))
//        } else {
//            showToast("您需要安装微信客户端")
//        }
    }
    /**
     * 将数据集合 转化成ArrayList<ArrayList></ArrayList><String>>
     * @return
    </String> */
    private fun getRecordData(): ArrayList<Any> {
        recordList = ArrayList<Any>()
        for (i in mList!!.indices) {
            val student: PlanItemWithClientList = mList[i]
            val beanList = ArrayList<String>()
//            beanList.add(student.client.name)
//            beanList.add(student.model.type)
//            beanList.add(student.model.name)
//            beanList.add(student.planItem.num.handlerNull())
//            beanList.add(student.planItem.remark.handlerNull())
            recordList!!.add(beanList)
        }
        return recordList as ArrayList<Any>
    }

    override fun finish() {
        if (mList.isEmpty()) {
            mViewModel.deletePlan(planDao, planId)
        }
        super.finish()
    }

    fun dealData(list:List<PlanItemWithClient>):List<PlanItemWithClientList>{
        val clientIdMap: HashMap<String, ArrayList<PlanItemWithClient>> = HashMap()
        val returnList=ArrayList<PlanItemWithClientList>()
        for (item in list) {
            val clientId: String = item.client.id
            if (!clientIdMap.containsKey(clientId)) {
                clientIdMap.put(clientId, ArrayList())
            }
           clientIdMap[clientId]?.add(item)
        }
        clientIdMap.forEach { (clientId, planItemList) ->
            // 处理 clientId 和对应的 planItemList
            val item=PlanItemWithClientList()
            item.clientId=clientId
            item.list=planItemList
            if(planItemList.size>0){
                item.clientName=planItemList[0].client.name
                returnList.add(item)
            }

        }
        return returnList
    }
//    fun dealData(list:List<PlanItemWithClient>):List<PlanItemWithClientList>{
//        val returnList=ArrayList<PlanItemWithClientList>()
//        for (item in list) {
//            val clientId: String = item.client.id
//            if(!containsClientId(returnList,clientId)){
//                val bean= PlanItemWithClientList()
//                bean.clientId=item.client.id
//                bean.clientName=item.client.name
//            }
//            bean.list.add(item)
//        }
//        return returnList
//    }
    fun makeDir(dir: File) {
        if (!dir.parentFile.exists()) {
            makeDir(dir.parentFile)
        }
        dir.mkdir()
    }
    fun newUpLoad(name:String,FILE_PATH:File){
        val AK = "0OKWE5DLGUZI7ZJO5SA1" // 替换为您的AK
        val SK = "iEr8cjx0QP8dxxKvDu17CWiPBzYA7M6NlSsc8pZa" // 替换为您的SK
        val ENDPOINT = "obs.cn-north-4.myhuaweicloud.com" // 替换为您的OBS Endpoint
        val BUCKET_NAME = "pictures-6ab5" // 替换为您的存储桶名称
        val obsClient = ObsClient(AK, SK, ENDPOINT)
        try {
            val file = FILE_PATH
            val inputStream = FileInputStream(file)
            val putObjectRequest = PutObjectRequest(BUCKET_NAME, name, inputStream)
            val putObjectResult = obsClient.putObject(putObjectRequest)
           // println("Uploaded file with UUID: ${putObjectResult.uploadId}")
        } catch (e: ObsException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            try {
                obsClient.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }
    fun updateObs(){
        // 您的工程中可以只保留一个全局的ObsClient实例
// ObsClient是线程安全的，可在并发场景下使用
        // 您的工程中可以只保留一个全局的ObsClient实例
// ObsClient是线程安全的，可在并发场景下使用
        var obsClient: ObsClient? = null
        try {
            val endPoint = "https://obs.cn-east-3.myhuaweicloud.com"
            val ak = "0OKWE5DLGUZI7ZJO5SA1"
            val sk = "iEr8cjx0QP8dxxKvDu17CWiPBzYA7M6NlSsc8pZa"
            // 创建ObsClient实例
            obsClient = ObsClient(ak, sk, endPoint)
            val file = File(filesDir, "my_docs")
            val newFile=File(file, "计划表.xls")
            // 调用接口进行操作，例如上传对象，其中localfile为待上传的本地文件路径，需要指定到具体的文件名
            val response: HeaderResponse =
                obsClient.putObject("pictures-6ab5", "objectname", newFile)
            Log.i("PutObject", response.toString())
        } catch (e: ObsException) {
            Log.e("PutObject", "Response Code: " + e.responseCode)
            Log.e("PutObject", "Error Message: " + e.errorMessage)
            Log.e("PutObject", "Error Code:       " + e.errorCode)
            Log.e("PutObject", "Request ID:      " + e.errorRequestId)
            Log.e("PutObject", "Host ID:           " + e.errorHostId)
        } finally {
            // 关闭ObsClient实例，如果是全局ObsClient实例，可以不在每个方法调用完成后关闭
            // ObsClient在调用ObsClient.close方法关闭后不能再次使用
            if (obsClient != null) {
                try {
                    obsClient.close()
                } catch (e: IOException) {
                }
            }
        }

    }

    override fun onItemDelete(position: Int, data: Details) {
        commonDialog("是否删除改数据"){
            mViewModel.deletePlanItem(planItemDao,data.code)
        }
    }

}